package ch.ethz.inf.shop;

import java.io.IOException;
import java.lang.reflect.Field;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import ch.ethz.inf.shop.model.Comment;
import ch.ethz.inf.shop.model.DatastoreInterface;
import ch.ethz.inf.shop.model.Product;
import ch.ethz.inf.shop.util.UserManagement;
import ch.ethz.inf.shop.util.html.BeanTableHelper;

/**
 * Servlet implementation class of Product Details Page
 */
@WebServlet(description = "Displays a specific product.", urlPatterns = { "/Product" })
public final class ProductServlet extends HttpServlet {
	private static final Logger LOGGER = Logger.getLogger(ProductServlet.class);
	public static final String CURRENT_PRODUCT = "currentProduct";
	private static final String PRODUCT_ID = "productId";
	private static final long serialVersionUID = 1L;
	private final DatastoreInterface dbInterface = new DatastoreInterface();

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	@Override
	protected final void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {

		final HttpSession session = request.getSession(true);

		final String idString = request.getParameter(PRODUCT_ID);
		if (idString == null) {
			this.getServletContext().getRequestDispatcher("/Products").forward(request, response);
		}

		try {

			final Integer id = Integer.parseInt(idString);
			final String like = request.getParameter("like");
			if (like != null) {
				dbInterface.addLike(UserManagement.getCurrentlyLoggedInUser(session), id);
			}

			final String addToCart = request.getParameter("addToCart");

			if (addToCart != null) {
				dbInterface.addToShoppingCart(UserManagement.getCurrentlyLoggedInUser(session), id);
			}
			final Product product = this.dbInterface.getProductById(id);

			final BeanTableHelper<Product> table = new BeanTableHelper<Product>("product", "productTable", Product.class);

			for (Field f : Product.class.getDeclaredFields()) {
				Title titleAnnotation = f.getAnnotation(Title.class);
				if (titleAnnotation != null && titleAnnotation.isVisible()) {
					table.addBeanColumn(titleAnnotation.text(), f.getName());
				} else if (titleAnnotation == null) {
					table.addBeanColumn(f.getName(), f.getName());
				}
			}

			if (UserManagement.getCurrentlyLoggedInUser(session) != null) {
				table.addLinkColumn("Like!", "<img src=\"images/face-grin.png\" alt=\"Like!\"/>", "Product?like=true&productId=", PRODUCT_ID);
				table.addLinkColumn("Add to shoppingCart:", "<img src=\"images/list-add.png\" alt=\"Add to shopping cart\"/>",
						"Product?addToCart=true&productId=", PRODUCT_ID);
			}

			table.addObject(product);
			table.setVertical(true);

			session.setAttribute("productTable", table);

			final BeanTableHelper<Comment> commentTable = new BeanTableHelper<Comment>("comments", "productsTable", Comment.class);
			for (Field f : Comment.class.getDeclaredFields()) {
				Title titleAnnotation = f.getAnnotation(Title.class);
				if (titleAnnotation != null && titleAnnotation.isVisible()) {
					commentTable.addBeanColumn(titleAnnotation.text(), f.getName());
				} else if (titleAnnotation == null) {
					commentTable.addBeanColumn(f.getName(), f.getName());
				}
			}
			commentTable.addObjects(dbInterface.getCommentsByProduct(product));

			commentTable.setVertical(false);

			session.setAttribute("commentTable", commentTable);
			session.setAttribute(CURRENT_PRODUCT, product);

		} catch (final Exception ex) {

			LOGGER.error("", ex);
			this.getServletContext().getRequestDispatcher("/Products").forward(request, response);

		}

		this.getServletContext().getRequestDispatcher("/Product.jsp").forward(request, response);

	}

	@Override
	protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {

		final String comment = req.getParameter("comment");
		final HttpSession session = req.getSession(true);
		if (comment == null) {
			this.getServletContext().getRequestDispatcher("/Products").forward(req, resp);
		}

		Product product = (Product) session.getAttribute(CURRENT_PRODUCT);
		Comment c = new Comment(comment, 0, product, UserManagement.getCurrentlyLoggedInUser(session), null);
		dbInterface.saveComment(c);
		doGet(req, resp);
	}
}
